package com.personal.dataanalyse.reportmanage.base;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import com.personal.core.bean.TwoTuple;
import com.personal.core.data.DataColumn;
import com.personal.core.data.DataColumns;
import com.personal.core.data.DataRow;
import com.personal.core.data.DataRows;
import com.personal.core.data.DataTable;
import com.personal.core.utils.Assert;
import com.personal.core.utils.CoreUtil;
import com.personal.core.utils.ReGularUtil;
import com.personal.dataanalyse.consts.FieldConsts;
import com.personal.dataanalyse.enums.FieldDataTypeEnum;
import com.personal.dataanalyse.enums.ModelFieldTypeEnum;
import com.personal.dataanalyse.enums.XyTypeEnum;
import com.personal.dataanalyse.reportmanage.entity.ConditionInfo;
import com.personal.dataanalyse.reportmanage.entity.DataColumnReportEx;
import com.personal.dataanalyse.reportmanage.entity.DataRowReportEx;
import com.personal.dataanalyse.reportmanage.entity.ReportHeader;
import com.personal.dataanalyse.reportmanage.util.ModelUtil;
import com.personal.dataconvert.bean.CombineColumnConfig;
import com.personal.dataconvert.bean.HeaderConfig;

/**
 * 模型解析器(包内权限)
 * @author cuibo
 *
 */
final class ModelAnalyzer
{
	private ModelAnalyzer()
	{
	}
	
    /**
     * 创建报表表行信息
     * @param model
     * @param table  已经填充好列信息的DataTable
     * @return
     * @throws Exceptions
     */
    public static DataRows createDataRowCollection(DataAnalyseModel model, DataTable table) throws Exception
    {
        Assert.isNotNull(model, "报表配置信息为空！");
        List<AnalyseFactorInfo> allFields = getCreateRowFields(model);
        // cb 第一步仍然转成DataColumnCollection，然后在转成DataRowCollection，复用DataColumnCollection中复杂的代码
        DataColumns columns = new DataColumns();
        TwoTuple<DataColumns, List<ReportHeader>> singleColumns = null;
        DataColumns singleCollection = null;
        
        // 所有的纵向合并配置
        Set<CombineColumnConfig> zxCombineConfigs = new HashSet<CombineColumnConfig>();
        Set<CombineColumnConfig> singleCombineConfigs = null;
        
        // 当前已经生成的行数
        int currentRowNum = 0;
        for (AnalyseFactorInfo filed : allFields)
        {
            singleColumns = filed.getDataColumnCollection();
            if (singleColumns == null || singleColumns.getA() == null || singleColumns.getA().isEmpty())
            {
                continue;
            }
            singleCollection = singleColumns.getA();
            columns.addAll(singleCollection);
            singleCombineConfigs = ModelUtil.calZxCombineConfigs(singleColumns.getB());
            if (singleCombineConfigs != null && !singleCombineConfigs.isEmpty())
            {
                // 需要把行号全部加上上面维度生成的行号
                for (CombineColumnConfig combineColumnConfig : singleCombineConfigs)
                {
                    combineColumnConfig.setMinRowScope(combineColumnConfig.getMinRowScope() + currentRowNum);
                    combineColumnConfig.setMaxRowScope(combineColumnConfig.getMaxRowScope() + currentRowNum);
                }
                zxCombineConfigs.addAll(singleCombineConfigs);
            }
            currentRowNum += singleCollection.size();
        }
        // DataColumnCollections 转DataRowCollections
        if (columns == null || columns.isEmpty())
        {
            return null;
        }
        // 最后处理计算列  2017 09 13 行列转换的不需要处理计算列
        if (model.isTransRowCol())
        {
            for (DataColumn dataColumn : columns)
            {
                if (!(dataColumn instanceof DataColumnReportEx))
                {
                    continue;
                }
                DataColumnReportEx columnEx = (DataColumnReportEx) dataColumn;
                if (ModelFieldTypeEnum.计算列.toString().equals(columnEx.getFieldType()))
                {
                    HeaderConfig parent = columnEx.getHeaderConfig() == null ? null : columnEx.getHeaderConfig().getParent();
                    ModelUtil.handleCalColumnFieldSql(model, parent == null ? "" : parent.getPath(), columns, columnEx);
                }
            }
        }
        
        DataRows result = new DataRows();
        DataColumnReportEx reportEx = null;
        // Y轴维度的最大深度
        // 如果是行列转换model，只能拿Y轴的有效深度。在添加另一个方向的维度列时也处理了
        int maxDeep = 0;
        if (model.isTransRowCol())
        {
            maxDeep = ModelUtil.getTransRowColMaxYGroupFieldDeep(model.getyGroupFields());
            // 需要加上指标列
            maxDeep++;
        } else
        {
            maxDeep = ModelUtil.getMaxGroupFieldDeep(model.getyGroupFields());
        }
        for (int i = 0; i < columns.size(); i++)
        {
            DataColumn dataColumn = columns.get(i);
            if (!(dataColumn instanceof DataColumnReportEx))
            {
                continue;
            }
            reportEx = (DataColumnReportEx) dataColumn;
            result.add(reportEx.toDataRowReportEx(maxDeep, table, i));
        }
        // 此时的zxCombineConfigs还只是列号，需要替换为列名
        for (CombineColumnConfig config : zxCombineConfigs)
        {
            if (table.getColumns().size() >= config.getColumnIndex() + 1)
            {
                DataColumn dataColumn = table.getColumns().get(config.getColumnIndex());
                if (!(dataColumn instanceof DataColumnReportEx))
                {
                    continue;
                }
                reportEx = (DataColumnReportEx) dataColumn;
                config.setColumnValue(table.getColumns().get(config.getColumnIndex()).getColumnName());
                // 添加纵向合并
                reportEx.getCombineConfigs().add(config);
            }
        }
        return result;
    }
    
    /**
     * 获取创建行的分析因子
     * @param model
     * @return
     */
    private static List<AnalyseFactorInfo> getCreateRowFields(DataAnalyseModel model)
    {
        List<AnalyseFactorInfo> allFields = new ArrayList<AnalyseFactorInfo>();
        // 是XTotalModel 需要添加指标值行
        if (model.isXSingleGroupTotalModel())
        {
            QuotaInfo info = model.createTargetValueQuotaInfo(); 
            allFields.add(info);
        }
        // 非行列翻转使用yGroupFields构建行
        if (model.getyGroupFields() != null)
        {
            allFields.addAll(model.getyGroupFields());
        }
        // 是行列转换才加这两列
        if (model.isTransRowCol())
        {
            if (model.getColumnFields() != null)
            {
                allFields.addAll(model.getColumnFields());
            }
            if (model.getCalFields() != null)
            {
                allFields.addAll(model.getCalFields());
            }
        }
        if (allFields.isEmpty())
        {
            return allFields;
        }
        // 排序
        Collections.sort(allFields, new Comparator<AnalyseFactorInfo>()
        {
            @Override
            public int compare(AnalyseFactorInfo o1, AnalyseFactorInfo o2)
            {
                if (o1.getFieldOrder() == o2.getFieldOrder())
                {
                    return 0;
                }
                return o1.getFieldOrder() - o2.getFieldOrder() > 0 ? 1 : -1;
            }
        });
        return allFields;
    }

    /**
     * 创建报表表列信息
     * @param model
     * @return
     * @throws Exception 
     */
    public static TwoTuple<DataColumns, List<ReportHeader>> createDataColumnCollection(DataAnalyseModel model) throws Exception
    {
        Assert.isNotNull(model, "报表配置信息为空！");
        List<AnalyseFactorInfo> allFields = getCreateColumnFields(model);
        // 列信息
        DataColumns columnCollection = new DataColumns();
        TwoTuple<DataColumns, List<ReportHeader>> singleColumns = null;
        // 表头配置
        List<ReportHeader> headerConfigs = new ArrayList<ReportHeader>();
        
        DataColumns singleCollection = null;
        for (AnalyseFactorInfo modelField : allFields)
        {
            singleColumns = modelField.getDataColumnCollection();
            if (singleColumns == null || singleColumns.getA() == null || singleColumns.getA().isEmpty())
            {
                continue;
            }
            singleCollection = singleColumns.getA();
            columnCollection.addAll(singleCollection);
            headerConfigs.addAll(singleColumns.getB());
        }
        
        // 最后处理计算列  2017 09 13 行列转换的不需要处理计算列
        if (!model.isTransRowCol())
        {
            for (DataColumn dataColumn : columnCollection)
            {
                if (!(dataColumn instanceof DataColumnReportEx))
                {
                    continue;
                }
                DataColumnReportEx columnEx = (DataColumnReportEx) dataColumn;
                if (ModelFieldTypeEnum.计算列.toString().equals(columnEx.getFieldType()))
                {
                    HeaderConfig parent = columnEx.getHeaderConfig() == null ? null : columnEx.getHeaderConfig().getParent();
                    ModelUtil.handleCalColumnFieldSql(model, parent == null ? "" : parent.getPath(), columnCollection, columnEx);
                }
            }
        }
        
        // 添加另外一个方向维度的名称列
        addOtherDirectionGroup(model, columnCollection, headerConfigs);
        TwoTuple<DataColumns, List<ReportHeader>> result = new TwoTuple<DataColumns, List<ReportHeader>>(columnCollection, headerConfigs);
        return result;
    }
    
    /**
     * 获取创建列的所有分析因子
     * @param model
     * @return
     */
    private static List<AnalyseFactorInfo> getCreateColumnFields(DataAnalyseModel model)
    {
        List<AnalyseFactorInfo> allFields = new ArrayList<AnalyseFactorInfo>();
        if (model.getxGroupFields() != null)
        {
            allFields.addAll(model.getxGroupFields());
        }
        // 不是行列转换才加这两列
        if (!model.isTransRowCol())
        {
            if (model.getColumnFields() != null)
            {
                allFields.addAll(model.getColumnFields());
            }
            if (model.getCalFields() != null)
            {
                allFields.addAll(model.getCalFields());
            }
        }
        // 排序
        Collections.sort(allFields, new Comparator<AnalyseFactorInfo>()
        {
            @Override
            public int compare(AnalyseFactorInfo o1, AnalyseFactorInfo o2)
            {
                if (o1.getFieldOrder() == o2.getFieldOrder())
                {
                    return 0;
                }
                return o1.getFieldOrder() - o2.getFieldOrder() > 0 ? 1 : -1;
            }
        });
        // 是YTotalModel 需要添加指标值列
        if (model.isYSingleGroupTotalModel())
        {
            QuotaInfo info = model.createTargetValueQuotaInfo();
            info.createTargetValueQuotaInfo();
            allFields.add(info);
        }
        return allFields;
    }

    /**
     * 添加另外一个方向维度的名称列
     * @param model
     * @param result
     * @param headerConfigs  表头配置
     * @throws Exception
     */
    private static void addOtherDirectionGroup(DataAnalyseModel model, DataColumns result, List<ReportHeader> headerConfigs) throws Exception
    {
        int maxDeep = 0;
        
        // 是否是行列转换model的单指标模型：需要隐藏指标列
        boolean isSingleQuo = model.isYSingleQuoModel();
        if (model.isTransRowCol())
        {
            maxDeep = ModelUtil.getTransRowColMaxYGroupFieldDeep(model.getyGroupFields());
        } else
        {
            maxDeep = ModelUtil.getMaxGroupFieldDeep(model.getyGroupFields());
        }
        // 报表列 
        DataColumnReportEx reportEx = null;
        // 指标值列序号
        if (maxDeep > 0)
        {
            // 指定深度的所有维度
            List<DimensionInfo> fields = null;
            StringBuilder columnLabel = null;
            
            QuotaInfo columnField = null;
            for (int i = 1; i <= maxDeep; i++)
            {
                fields = ModelUtil.getGroupFieldsByDeep(model.getyGroupFields(), i);
                if (fields == null)
                {
                    reportEx = new DataColumnReportEx("无法识别的列名");
                    reportEx.setColumnName(CoreUtil.newShortUuId());
                    reportEx.setDataType(FieldDataTypeEnum.字符串.toString());
                    reportEx.setOtherGroupCol(true);
                    reportEx.setMatchData(true);
                    result.add(i - 1, reportEx);
                    // 添加表头配置
                    headerConfigs.add(i - 1, reportEx.toHeaderConfig());
                } else
                {
                    columnLabel = new StringBuilder();
                    for (DimensionInfo groupField : fields)
                    {
                        if (groupField.hasColCol())
                        {
                            columnField = groupField.getColumnFields().get(0);
                        }
                        columnLabel.append(groupField.getFieldName()).append("/");
                    }
                    // 样式等信息以第一个为准
                    reportEx = fields.get(0).toDataColumnReportEx();
                    reportEx.setColumnName(CoreUtil.newShortUuId());
                    reportEx.setColumnLable(columnLabel.deleteCharAt(columnLabel.length() - 1).toString());
                    // 另一个方向的datafieldSql为空。
                    reportEx.setFieldDataSql(null);
                    // 数据类型为字符串
                    reportEx.setDataType(FieldDataTypeEnum.字符串.toString());
                    reportEx.setOtherGroupCol(true);
                    reportEx.setMatchData(true);
                    result.add(i - 1, reportEx);
                    // 添加表头配置
                    headerConfigs.add(i - 1, reportEx.toHeaderConfig());
                }
            }
            if (columnField != null)
            {
                // 样式等信息以第一个为准
                reportEx = columnField.toDataColumnReportEx();
                reportEx.setColumnName(CoreUtil.newShortUuId());
                reportEx.setColumnLable(CoreUtil.isEmpty(model.getHeadTargetName()) ? FieldConsts.TARGET_COL : model.getHeadTargetName());
                // 手填了就不加单位
                reportEx.setHeaderAddUnit(CoreUtil.isEmpty(model.getHeadTargetName()));
                reportEx.setWidth(FieldConsts.TARGET_WIDTH);
                reportEx.setWidth(FieldConsts.TARGET_WIDTH);
                reportEx.setAlign(HeaderConfig.LEFT);
                reportEx.setStyleClass(FieldConsts.TARGET_CSS);
                reportEx.setDataType(FieldDataTypeEnum.字符串.toString());
                // 另一个方向的datafieldSql为空。
                reportEx.setFieldDataSql(null);
                reportEx.setOtherGroupCol(true);
                reportEx.setMatchData(true);
                // 如果是行列转换model的单指标模型：需要隐藏指标列
                ReportHeader config = reportEx.toHeaderConfig();
                reportEx.setDisplay(!isSingleQuo);
                config.setDisplay(!isSingleQuo);
                result.add(maxDeep, reportEx);
                // 添加表头配置
                headerConfigs.add(maxDeep, config);
            }
        } else if (model.isXSingleGroupTotalModel())
        {
            // 是 XTotalModel 需要添加指标值列
            reportEx = new DataColumnReportEx();
            reportEx.setColumnName(CoreUtil.newShortUuId());
            reportEx.setColumnLable(CoreUtil.isEmpty(model.getHeadTargetName()) ? FieldConsts.TARGET_COL : model.getHeadTargetName());
            // 手填了就不加单位
            reportEx.setHeaderAddUnit(CoreUtil.isEmpty(model.getHeadTargetName()));
            reportEx.setWidth(FieldConsts.TARGET_WIDTH);
            reportEx.setWidth(FieldConsts.TARGET_WIDTH);
            reportEx.setAlign(HeaderConfig.LEFT);
            reportEx.setStyleClass(FieldConsts.TARGET_CSS);
            reportEx.setDataType(FieldDataTypeEnum.字符串.toString());
            reportEx.setOtherGroupCol(true);
            reportEx.setMatchData(true);
            result.add(0, reportEx);
            // 添加表头配置
            headerConfigs.add(0, reportEx.toHeaderConfig());
        } else if (model.isYSingleGroupTotalModel())
        {
            // 是 YTotalModel 需要添加指标列
            reportEx = new DataColumnReportEx();
            reportEx.setColumnName(CoreUtil.newShortUuId());
            reportEx.setColumnLable(CoreUtil.isEmpty(model.getHeadTargetName()) ? FieldConsts.TARGET_COL : model.getHeadTargetName());
            // 手填了就不加单位
            reportEx.setHeaderAddUnit(CoreUtil.isEmpty(model.getHeadTargetName()));
            reportEx.setWidth(FieldConsts.TARGET_WIDTH);
            reportEx.setWidth(FieldConsts.TARGET_WIDTH);
            reportEx.setAlign(HeaderConfig.LEFT);
            reportEx.setStyleClass(FieldConsts.TARGET_CSS);
            reportEx.setDataType(FieldDataTypeEnum.字符串.toString());
            reportEx.setOtherGroupCol(true);
            reportEx.setMatchData(true);
            result.add(0, reportEx);
            // 添加表头配置
            headerConfigs.add(0, reportEx.toHeaderConfig());
        } else if (model.getColumnFields() != null && !model.getColumnFields().isEmpty() && model.getColumnFields().get(0).getXy() == XyTypeEnum.Y)
        {
            // Y轴方向只有指标，X轴方向有维度的情况
            reportEx = new DataColumnReportEx();
            reportEx.setColumnName(CoreUtil.newShortUuId());
            reportEx.setColumnLable(CoreUtil.isEmpty(model.getHeadTargetName()) ? FieldConsts.TARGET_COL : model.getHeadTargetName());
            // 手填了就不加单位
            reportEx.setHeaderAddUnit(CoreUtil.isEmpty(model.getHeadTargetName()));
            reportEx.setWidth(FieldConsts.TARGET_WIDTH);
            reportEx.setWidth(FieldConsts.TARGET_WIDTH);
            reportEx.setAlign(HeaderConfig.LEFT);
            reportEx.setStyleClass(FieldConsts.TARGET_CSS);
            reportEx.setDataType(FieldDataTypeEnum.字符串.toString());
            reportEx.setOtherGroupCol(true);
            reportEx.setMatchData(true);
            result.add(0, reportEx);
            // 添加表头配置
            headerConfigs.add(0, reportEx.toHeaderConfig());
        }
    }
    
    
    /**
     * 加载所有需要查询的指标名称
     * @param structTable  结构DataTable
     * @return
     */
    public static Set<String> loadAllQueryTargetNames(DataTable structTable)
    {
        if (structTable == null)
        {
            return null;
        }
        Set<String> result = new HashSet<String>();
        DataColumnReportEx columnReportEx = null;
        
        // 列查询数据
        Set<String> singleResult = null;
        
        //  单个fieldDataSql
        String[] arr = null;
        for (DataColumn column : structTable.getColumns())
        {
            if (!(column instanceof DataColumnReportEx))
            {
                continue;
            }
            columnReportEx = (DataColumnReportEx)column;
            singleResult = loadConditionQueryTargetNames(columnReportEx.getConditions());
            if (singleResult != null && !singleResult.isEmpty())
            {
                result.addAll(singleResult);
            }
            // 只需要查询列维度指标和普通列的数据
            if (ModelFieldTypeEnum.isQueryTargetNamesField(columnReportEx.getFieldType()))
            {
                if (columnReportEx.isExpType())
                {
                    arr = ReGularUtil.EXPANDKHPATTERNANDABS.split(columnReportEx.getFieldDataSql());
                    if (arr == null || arr.length == 0)
                    {
                        continue;
                    }
                    for (String string : arr)
                    {
                        string = string.trim();
                        if (ModelUtil.checkLegalFieldDataSql(string))
                        {
                            result.add(string);
                        }
                    }
                } else
                {
                    if (ModelUtil.checkLegalFieldDataSql(columnReportEx.getFieldDataSql()))
                    {
                        result.add(columnReportEx.getFieldDataSql());
                    }
                }
            }
        }
        // 行查询数据
        DataRowReportEx rowReportEx = null;
        for (DataRow row : structTable.getRows())
        {
            if (!(row instanceof DataRowReportEx))
            {
                continue;
            }
            rowReportEx = (DataRowReportEx) row;
            singleResult = loadConditionQueryTargetNames(rowReportEx.getConditions());
            if (singleResult != null && !singleResult.isEmpty())
            {
                result.addAll(singleResult);
            }
        }
        return result;
    }

    /**
     * 加载条件中的查询指标名
     * @param conditions
     * @return
     */
    private static Set<String> loadConditionQueryTargetNames(List<ConditionInfo> conditions)
    {
        if (conditions == null || conditions.isEmpty())
        {
            return null;
        }
        Set<String> result = new HashSet<String>();
        // 条件
        String[] arr = null;
        for (ConditionInfo condition : conditions)
        {
            if (condition.isExpType())
            {
                arr = ReGularUtil.EXPANDKHPATTERNANDABS.split(condition.getKey());
                if (arr == null || arr.length == 0)
                {
                    continue;
                }
                for (String string : arr)
                {
                    string = string.trim();
                    if (ModelUtil.checkLegalFieldDataSql(string))
                    {
                        result.add(string);
                    }
                }
            } else
            {
                if (ModelUtil.checkLegalFieldDataSql(condition.getKey()))
                {
                    result.add(condition.getKey());
                }
            }
        }
        return result;
    }
}
